package remotecache

import (
	"context"
	"go-caipu/pkg/setting"
	"go-caipu/pkg/util"
	"time"

	"github.com/redis/go-redis/v9"
)

type RedisStore struct {
	client *redis.Client
}

// NewRedisStore 创建一个新的 RedisStore 实例

func NewRedisStore(client *redis.Client) *RedisStore {
	return &RedisStore{
		client: client,
	}
}

func ProviceRedisClient(cfg *setting.Cfg) *redis.Client {
	if cfg.RedisConfig == nil {
		return nil
	}
	options := &redis.Options{
		Addr:     cfg.RedisConfig.Address,
		Username: cfg.RedisConfig.User,
		Password: cfg.RedisConfig.Password,
		DB:       util.StringToInt(cfg.RedisConfig.Database),
		//MaxRetries:   opts.RedisConfig.
		//MinIdleConns: opts.MinIdleConns,
		//DialTimeout:  opts.DialTimeout,
		//ReadTimeout:  opts.ReadTimeout,
		//WriteTimeout: opts.WriteTimeout,
		//PoolTimeout:  opts.PoolTimeout,
		//PoolSize:     opts.PoolSize,
	}
	return redis.NewClient(options)
}

// Set 设置值，ttl为过期时间，单位为秒
func (r *RedisStore) Set(key string, value interface{}, ttl int) error {
	ctx := context.Background()
	return r.client.Set(ctx, key, value, time.Duration(ttl)*time.Second).Err()
}

// Get 取值，并返回是否成功
func (r *RedisStore) Get(key string) (interface{}, bool) {
	ctx := context.Background()
	val, err := r.client.Get(ctx, key).Result()
	if err == redis.Nil {
		return nil, false
	} else if err != nil {
		return nil, false
	}
	return val, true
}

// Gets 批量取值，返回成功取值的map即不存在的值
func (r *RedisStore) Gets(keys []string, prefix string) (map[string]interface{}, []string) {
	ctx := context.Background()
	result := make(map[string]interface{})
	var notFound []string

	for _, key := range keys {
		fullKey := prefix + key
		val, err := r.client.Get(ctx, fullKey).Result()
		if err == redis.Nil {
			notFound = append(notFound, key)
		} else if err != nil {
			notFound = append(notFound, key)
		} else {
			result[key] = val
		}
	}

	return result, notFound
}

// Sets 批量设置值，所有的key都会加上prefix前缀
func (r *RedisStore) Sets(values map[string]interface{}, prefix string) error {
	ctx := context.Background()
	pipe := r.client.Pipeline()

	for key, value := range values {
		fullKey := prefix + key
		pipe.Set(ctx, fullKey, value, 0)
	}

	_, err := pipe.Exec(ctx)
	return err
}

// Delete 删除值
func (r *RedisStore) Delete(keys []string, prefix string) error {
	ctx := context.Background()
	fullKeys := make([]string, len(keys))
	for i, key := range keys {
		fullKeys[i] = prefix + key
	}
	return r.client.Del(ctx, fullKeys...).Err()
}

// Persist Save in-memory cache to disk
func (r *RedisStore) Persist(path string) error {
	// Redis 本身是持久化的，不需要额外操作
	return nil
}

// Restore cache from disk
func (r *RedisStore) Restore(path string) error {
	// Redis 本身是持久化的，不需要额外操作
	return nil
}
